package com.huidu.bitrade.task;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huidu.bitrade.constant.ActivityType;
import com.huidu.bitrade.constant.SystemConfigConstants;
import com.huidu.bitrade.constant.TransactionType;
import com.huidu.bitrade.entity.*;
import com.huidu.bitrade.service.*;
import com.huidu.bitrade.util.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
@RequiredArgsConstructor
public class HdzOrderTask {

    private final ActivityHdzOrderService activityHdzOrderService;
    private final MemberWalletService memberWalletService;
    private final SystemConfigService systemConfigService;
    private final ActivityHdzOrderDetailService activityHdzOrderDetailService;
    private final MemberTransactionService memberTransactionService;

    /**
     * 每天凌晨2:30，修改release余额,更新活动总池
     */
    @Scheduled(cron = "0 30 2 * * *")
    @Transactional(rollbackFor = Exception.class)
    public void release() {
        log.info("===============开始更新hdz，ToRelease==========");
        //前一天最小时间
        LocalDateTime dateTime = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MIN);
        //获取时间戳
        long timestamp = dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        //修改状态，将参与数量加入release账号
       List<ActivityHdzOrder> orderList = activityHdzOrderService.list(Wrappers.<ActivityHdzOrder>lambdaQuery()
                .eq(ActivityHdzOrder::getStatus,0)//未满足t+1的
                .le(ActivityHdzOrder::getCreateTime, timestamp));//比前一天最小时间小的
        if(CollectionUtils.isNotEmpty(orderList)){
            for(ActivityHdzOrder order:orderList){
                order.setStatus(1);
            }
            activityHdzOrderService.updateBatchById(orderList);
        }
    }

    /**
     * 每天凌晨3:00，hdz质押生息记录
     */
    @Scheduled(cron = "0 00 3 * * *")
    @Transactional(rollbackFor = Exception.class)
    public void createDetail() {
        log.info("========HdzOrderTask.createDetail()开始执行==========");
        //查询所有需要发放利息的订单
        List<ActivityHdzOrder> orderList = activityHdzOrderService.list(Wrappers.<ActivityHdzOrder>lambdaQuery().eq(ActivityHdzOrder::getStatus,1));
        //hdz质押配置
        BigDecimal totalSupply = new BigDecimal(systemConfigService.getConfigValue(SystemConfigConstants.ACTIVITY_HDZ_AMOUNT));//质押总数量
        String numberDay = systemConfigService.getConfigValue(SystemConfigConstants.ACTIVITY_HDZ_DAY_NUMBER);//质押每日增长
        BigDecimal releaseDay = new BigDecimal(systemConfigService.getConfigValue(SystemConfigConstants.ACTIVITY_HDZ_DAY_RELEASE));//质押每日释放
        if(CollectionUtils.isEmpty(orderList)){
            log.info("========需要发放利息的订单为空==========");
            systemConfigService.updateConfigValue(String.valueOf(totalSupply.add(new BigDecimal(numberDay))),SystemConfigConstants.ACTIVITY_HDZ_AMOUNT);
            log.info("========HdzOrderTask.createDetail()执行完毕==========");
            return;
        }
        for(ActivityHdzOrder activityHdzOrder:orderList){
            release(activityHdzOrder,totalSupply,releaseDay);
        }
        systemConfigService.updateConfigValue(String.valueOf(totalSupply.add(new BigDecimal(numberDay))),SystemConfigConstants.ACTIVITY_HDZ_AMOUNT);

    }

    @Transactional(rollbackFor = Exception.class)
    public void release(ActivityHdzOrder order,BigDecimal totalSupply,BigDecimal releaseDay){
        //计算利息：订单当前余额/总池 * 周期释放额度(每天释放)
        BigDecimal interest = order.getNumber().multiply(releaseDay).divide(totalSupply,8, RoundingMode.DOWN);
        //修改订单当前余额,总利息
        order.setCurrentNumber(order.getCurrentNumber().add(interest));
        order.setInterest(order.getInterest().add(interest));
        order.setLastInterest(interest);
        activityHdzOrderService.updateById(order);
        //修改钱包torelease值
        MemberWallet memberWallet = memberWalletService.findByCoinUnitAndMemberId(order.getSymbol(),order.getMemberId());
        if (Objects.isNull(memberWallet)){
            log.error("=======HdzOrderTask：未找到用户钱包=======memberId{}",order.getMemberId());
            throw new RuntimeException("HdzOrderTask：未找到用户钱包=======memberId{}："+order.getMemberId());
        }
        //增加订单生息详情
        activityHdzOrderDetailService.save(ActivityHdzOrderDetail.builder()
                .amount(totalSupply)
                .memberId(order.getMemberId())
                .interestDay(interest)
                .orderId(order.getId())
                .number(order.getNumber())
                .releaseDay(releaseDay)
                .interest(order.getCurrentNumber().subtract(order.getNumber())).build());
        int row = memberWalletService.increaseBalance(memberWallet.getId(),interest);
        if(row<1){
            log.error("=======HdzOrderTask.createDetail：用户hdzrelease修改失败=======memberId{}",order.getMemberId());
            throw new IllegalArgumentException("修改用户hdzTorelease异常");
        }
        //添加流水
        MemberTransaction memberTransaction1 = new MemberTransaction();
        memberTransaction1.setFee(BigDecimal.ZERO);
        memberTransaction1.setAmount(interest);
        memberTransaction1.setMemberId(order.getMemberId());
        memberTransaction1.setSymbol(order.getSymbol());
        memberTransaction1.setType(TransactionType.STAKING_HDZ_INCOME);
        memberTransaction1.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction1.setRealFee("0");
        memberTransaction1.setDiscountFee("0");
        memberTransactionService.save(memberTransaction1);
    }
}
